// @HEADER
//*********************************************************************//
//  SiYuan: A numerical PDE solver                                     //
//  Copyright (2022) YUAN Xi                                           //
//  This Software is released under the BSD 2-Clause license detailed  //
//  in the file "LICENSE" in the top-level SiYuan directory            //
//*********************************************************************//
// @HEADER

#ifndef __FIELD_MANAGER_BUILDER_HPP__
#define __FIELD_MANAGER_BUILDER_HPP__

#include "PhysicsBlock.hpp"
#include "Neumann.hpp"
#include "Dirichlet.hpp"
#include "MaterialBase.hpp"

#include "Panzer_FieldManagerBuilder.hpp"

#include <string>
#include <vector>



namespace SiYuan {

/** This class defines a response based on a functional. */
  
class FieldManagerBuilder : public panzer::FieldManagerBuilder
{
public:
    FieldManagerBuilder(bool disablePhysicsBlockScatter=false,bool disablePhysicsBlockGather=false);

    void setupVolumeFieldManagers( const Teuchos::RCP<const panzer_stk::STK_Interface>& mesh,
                const std::vector<Teuchos::RCP<panzer::PhysicsBlock> >& physicsBlocks,
                const std::vector<panzer::WorksetDescriptor> & wkstDesc,
				const panzer::ClosureModelFactory_TemplateManager<panzer::Traits>& cm_factory,
				const Teuchos::ParameterList& closure_models,
                const panzer::LinearObjFactory<panzer::Traits> & lo_factory,
				const Teuchos::ParameterList& user_data,
                const panzer::GenericEvaluatorFactory & gEvalFact,
                bool closureModelByEBlock=false);

    void setupVolumeFieldManagers( const Teuchos::RCP<const panzer_stk::STK_Interface>& mesh,
                const std::vector<Teuchos::RCP<panzer::PhysicsBlock> >& physicsBlocks,
				const panzer::ClosureModelFactory_TemplateManager<panzer::Traits>& cm_factory,
				const Teuchos::ParameterList& closure_models,
                const panzer::LinearObjFactory<panzer::Traits> & lo_factory,
				const Teuchos::ParameterList& user_data);

    void buildMaterials(const Teuchos::ParameterList& matl_data);
    std::shared_ptr<Material> getMaterial(std::string& name) const
    { return _materials.at(name); }

    void setupDirichletFieldManager(const std::vector< Dirichlet<panzer::Traits::RealType> >& p,
                const Teuchos::RCP<const panzer_stk::STK_Interface>& mesh );
 //   const Teuchos::RCP< PHX::FieldManager<panzer::Traits> >&
 //   getDirichletFieldManager() const { return phx_dirichlet_field_manager_; }

    void setupNeumannFieldManager(const std::vector< NeumannBoundary >& bcs,
        const std::vector< CLoad >& cloads,
        const panzer::LinearObjFactory<panzer::Traits> & lo_factory,
        const std::vector<Teuchos::RCP<panzer::PhysicsBlock> >& physicsBlocks );

private:
    CMaterials _materials;

    //! Dirichlete field manager
    std::shared_ptr< PHX::FieldManager<panzer::Traits> > phx_neumann_field_manager_;
};

}

#endif
